package com.bcst.plugin;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;

import java.sql.Connection;
import java.util.Properties;

/*
 *@description 欢迎关注公众号 编程识堂,每日更新技术相关文章，关注我不迷路
 *@author 小堂
 *@create 2023/7/16 21:54
 */
@Intercepts ({//注意看这个⼤花括号，也就这说这⾥可以定义多个@Signature对多个地⽅拦截，都⽤这个拦截器
@Signature (type = StatementHandler.class, //这是指拦截哪个接⼝
        method = "prepare",//这个接⼝内的哪个⽅法名，不要拼错了
        args = { Connection.class, Integer.class}),//// 这是拦截的⽅法的⼊参，按顺序写到这，不要多也不要少，如果⽅法重载，可是要通过⽅法名和⼊参来确定唯⼀的
        })
public class MyPlugin implements Interceptor {

    /**
     * 拦截方法：只要被拦截的目标对象的目标方法被执行时，每次都会执行intercept方法
     * @param invocation
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("MyPlugin插件 目标方法被增强。。。。");
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
        return invocation.proceed();//原方法执行。。
    }

    /**
     * 主要为了把当前的拦截器生成代理保存到拦截链中
     * @Description 包装⽬标对象 为⽬标对象创建代理对象
     * @Param  target为要拦截的对象
     * @Return 代理对象
     */
    @Override
    public Object plugin(Object target) {
        System.out.println("MyPlugin插件将要包装的⽬标对象："+target);
        Object wrap = Plugin.wrap(target, this);
        return wrap;
    }

    /**
     * 获取配置文件的参数
     * @param properties
     */
    @Override
    public void setProperties(Properties properties) {
        System.out.println("获取配置文件的参数是："+properties);
    }
}
